{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "## 支持向量机（SVM）——鸢尾花数据集"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "6dc030b740319990"
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-04-24T07:06:45.450133Z",
     "start_time": "2025-04-24T07:06:45.445631Z"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "from sklearn import datasets\n",
    "from sklearn.model_selection import train_test_split, GridSearchCV,cross_val_score\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.svm import SVC\n",
    "from sklearn.metrics import accuracy_score, precision_recall_fscore_support, confusion_matrix, classification_report"
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 数据预处理与模型训练"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "39bd45bd677afc9e"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Best parameters: {'C': 0.1, 'gamma': 'scale', 'kernel': 'linear'}\n"
     ]
    },
    {
     "data": {
      "text/plain": "SVC(C=0.1, class_weight='balanced', kernel='linear', random_state=42)",
      "text/html": "<style>#sk-container-id-5 {\n  /* Definition of color scheme common for light and dark mode */\n  --sklearn-color-text: #000;\n  --sklearn-color-text-muted: #666;\n  --sklearn-color-line: gray;\n  /* Definition of color scheme for unfitted estimators */\n  --sklearn-color-unfitted-level-0: #fff5e6;\n  --sklearn-color-unfitted-level-1: #f6e4d2;\n  --sklearn-color-unfitted-level-2: #ffe0b3;\n  --sklearn-color-unfitted-level-3: chocolate;\n  /* Definition of color scheme for fitted estimators */\n  --sklearn-color-fitted-level-0: #f0f8ff;\n  --sklearn-color-fitted-level-1: #d4ebff;\n  --sklearn-color-fitted-level-2: #b3dbfd;\n  --sklearn-color-fitted-level-3: cornflowerblue;\n\n  /* Specific color for light theme */\n  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n  --sklearn-color-icon: #696969;\n\n  @media (prefers-color-scheme: dark) {\n    /* Redefinition of color scheme for dark theme */\n    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n    --sklearn-color-icon: #878787;\n  }\n}\n\n#sk-container-id-5 {\n  color: var(--sklearn-color-text);\n}\n\n#sk-container-id-5 pre {\n  padding: 0;\n}\n\n#sk-container-id-5 input.sk-hidden--visually {\n  border: 0;\n  clip: rect(1px 1px 1px 1px);\n  clip: rect(1px, 1px, 1px, 1px);\n  height: 1px;\n  margin: -1px;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 1px;\n}\n\n#sk-container-id-5 div.sk-dashed-wrapped {\n  border: 1px dashed var(--sklearn-color-line);\n  margin: 0 0.4em 0.5em 0.4em;\n  box-sizing: border-box;\n  padding-bottom: 0.4em;\n  background-color: var(--sklearn-color-background);\n}\n\n#sk-container-id-5 div.sk-container {\n  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n     but bootstrap.min.css set `[hidden] { display: none !important; }`\n     so we also need the `!important` here to be able to override the\n     default hidden behavior on the sphinx rendered scikit-learn.org.\n     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n  display: inline-block !important;\n  position: relative;\n}\n\n#sk-container-id-5 div.sk-text-repr-fallback {\n  display: none;\n}\n\ndiv.sk-parallel-item,\ndiv.sk-serial,\ndiv.sk-item {\n  /* draw centered vertical line to link estimators */\n  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n  background-size: 2px 100%;\n  background-repeat: no-repeat;\n  background-position: center center;\n}\n\n/* Parallel-specific style estimator block */\n\n#sk-container-id-5 div.sk-parallel-item::after {\n  content: \"\";\n  width: 100%;\n  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n  flex-grow: 1;\n}\n\n#sk-container-id-5 div.sk-parallel {\n  display: flex;\n  align-items: stretch;\n  justify-content: center;\n  background-color: var(--sklearn-color-background);\n  position: relative;\n}\n\n#sk-container-id-5 div.sk-parallel-item {\n  display: flex;\n  flex-direction: column;\n}\n\n#sk-container-id-5 div.sk-parallel-item:first-child::after {\n  align-self: flex-end;\n  width: 50%;\n}\n\n#sk-container-id-5 div.sk-parallel-item:last-child::after {\n  align-self: flex-start;\n  width: 50%;\n}\n\n#sk-container-id-5 div.sk-parallel-item:only-child::after {\n  width: 0;\n}\n\n/* Serial-specific style estimator block */\n\n#sk-container-id-5 div.sk-serial {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  background-color: var(--sklearn-color-background);\n  padding-right: 1em;\n  padding-left: 1em;\n}\n\n\n/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\nclickable and can be expanded/collapsed.\n- Pipeline and ColumnTransformer use this feature and define the default style\n- Estimators will overwrite some part of the style using the `sk-estimator` class\n*/\n\n/* Pipeline and ColumnTransformer style (default) */\n\n#sk-container-id-5 div.sk-toggleable {\n  /* Default theme specific background. It is overwritten whether we have a\n  specific estimator or a Pipeline/ColumnTransformer */\n  background-color: var(--sklearn-color-background);\n}\n\n/* Toggleable label */\n#sk-container-id-5 label.sk-toggleable__label {\n  cursor: pointer;\n  display: flex;\n  width: 100%;\n  margin-bottom: 0;\n  padding: 0.5em;\n  box-sizing: border-box;\n  text-align: center;\n  align-items: start;\n  justify-content: space-between;\n  gap: 0.5em;\n}\n\n#sk-container-id-5 label.sk-toggleable__label .caption {\n  font-size: 0.6rem;\n  font-weight: lighter;\n  color: var(--sklearn-color-text-muted);\n}\n\n#sk-container-id-5 label.sk-toggleable__label-arrow:before {\n  /* Arrow on the left of the label */\n  content: \"▸\";\n  float: left;\n  margin-right: 0.25em;\n  color: var(--sklearn-color-icon);\n}\n\n#sk-container-id-5 label.sk-toggleable__label-arrow:hover:before {\n  color: var(--sklearn-color-text);\n}\n\n/* Toggleable content - dropdown */\n\n#sk-container-id-5 div.sk-toggleable__content {\n  max-height: 0;\n  max-width: 0;\n  overflow: hidden;\n  text-align: left;\n  /* unfitted */\n  background-color: var(--sklearn-color-unfitted-level-0);\n}\n\n#sk-container-id-5 div.sk-toggleable__content.fitted {\n  /* fitted */\n  background-color: var(--sklearn-color-fitted-level-0);\n}\n\n#sk-container-id-5 div.sk-toggleable__content pre {\n  margin: 0.2em;\n  border-radius: 0.25em;\n  color: var(--sklearn-color-text);\n  /* unfitted */\n  background-color: var(--sklearn-color-unfitted-level-0);\n}\n\n#sk-container-id-5 div.sk-toggleable__content.fitted pre {\n  /* unfitted */\n  background-color: var(--sklearn-color-fitted-level-0);\n}\n\n#sk-container-id-5 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n  /* Expand drop-down */\n  max-height: 200px;\n  max-width: 100%;\n  overflow: auto;\n}\n\n#sk-container-id-5 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n  content: \"▾\";\n}\n\n/* Pipeline/ColumnTransformer-specific style */\n\n#sk-container-id-5 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n  color: var(--sklearn-color-text);\n  background-color: var(--sklearn-color-unfitted-level-2);\n}\n\n#sk-container-id-5 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n  background-color: var(--sklearn-color-fitted-level-2);\n}\n\n/* Estimator-specific style */\n\n/* Colorize estimator box */\n#sk-container-id-5 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n  /* unfitted */\n  background-color: var(--sklearn-color-unfitted-level-2);\n}\n\n#sk-container-id-5 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n  /* fitted */\n  background-color: var(--sklearn-color-fitted-level-2);\n}\n\n#sk-container-id-5 div.sk-label label.sk-toggleable__label,\n#sk-container-id-5 div.sk-label label {\n  /* The background is the default theme color */\n  color: var(--sklearn-color-text-on-default-background);\n}\n\n/* On hover, darken the color of the background */\n#sk-container-id-5 div.sk-label:hover label.sk-toggleable__label {\n  color: var(--sklearn-color-text);\n  background-color: var(--sklearn-color-unfitted-level-2);\n}\n\n/* Label box, darken color on hover, fitted */\n#sk-container-id-5 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n  color: var(--sklearn-color-text);\n  background-color: var(--sklearn-color-fitted-level-2);\n}\n\n/* Estimator label */\n\n#sk-container-id-5 div.sk-label label {\n  font-family: monospace;\n  font-weight: bold;\n  display: inline-block;\n  line-height: 1.2em;\n}\n\n#sk-container-id-5 div.sk-label-container {\n  text-align: center;\n}\n\n/* Estimator-specific */\n#sk-container-id-5 div.sk-estimator {\n  font-family: monospace;\n  border: 1px dotted var(--sklearn-color-border-box);\n  border-radius: 0.25em;\n  box-sizing: border-box;\n  margin-bottom: 0.5em;\n  /* unfitted */\n  background-color: var(--sklearn-color-unfitted-level-0);\n}\n\n#sk-container-id-5 div.sk-estimator.fitted {\n  /* fitted */\n  background-color: var(--sklearn-color-fitted-level-0);\n}\n\n/* on hover */\n#sk-container-id-5 div.sk-estimator:hover {\n  /* unfitted */\n  background-color: var(--sklearn-color-unfitted-level-2);\n}\n\n#sk-container-id-5 div.sk-estimator.fitted:hover {\n  /* fitted */\n  background-color: var(--sklearn-color-fitted-level-2);\n}\n\n/* Specification for estimator info (e.g. \"i\" and \"?\") */\n\n/* Common style for \"i\" and \"?\" */\n\n.sk-estimator-doc-link,\na:link.sk-estimator-doc-link,\na:visited.sk-estimator-doc-link {\n  float: right;\n  font-size: smaller;\n  line-height: 1em;\n  font-family: monospace;\n  background-color: var(--sklearn-color-background);\n  border-radius: 1em;\n  height: 1em;\n  width: 1em;\n  text-decoration: none !important;\n  margin-left: 0.5em;\n  text-align: center;\n  /* unfitted */\n  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n  color: var(--sklearn-color-unfitted-level-1);\n}\n\n.sk-estimator-doc-link.fitted,\na:link.sk-estimator-doc-link.fitted,\na:visited.sk-estimator-doc-link.fitted {\n  /* fitted */\n  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n  color: var(--sklearn-color-fitted-level-1);\n}\n\n/* On hover */\ndiv.sk-estimator:hover .sk-estimator-doc-link:hover,\n.sk-estimator-doc-link:hover,\ndiv.sk-label-container:hover .sk-estimator-doc-link:hover,\n.sk-estimator-doc-link:hover {\n  /* unfitted */\n  background-color: var(--sklearn-color-unfitted-level-3);\n  color: var(--sklearn-color-background);\n  text-decoration: none;\n}\n\ndiv.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n.sk-estimator-doc-link.fitted:hover,\ndiv.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n.sk-estimator-doc-link.fitted:hover {\n  /* fitted */\n  background-color: var(--sklearn-color-fitted-level-3);\n  color: var(--sklearn-color-background);\n  text-decoration: none;\n}\n\n/* Span, style for the box shown on hovering the info icon */\n.sk-estimator-doc-link span {\n  display: none;\n  z-index: 9999;\n  position: relative;\n  font-weight: normal;\n  right: .2ex;\n  padding: .5ex;\n  margin: .5ex;\n  width: min-content;\n  min-width: 20ex;\n  max-width: 50ex;\n  color: var(--sklearn-color-text);\n  box-shadow: 2pt 2pt 4pt #999;\n  /* unfitted */\n  background: var(--sklearn-color-unfitted-level-0);\n  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n}\n\n.sk-estimator-doc-link.fitted span {\n  /* fitted */\n  background: var(--sklearn-color-fitted-level-0);\n  border: var(--sklearn-color-fitted-level-3);\n}\n\n.sk-estimator-doc-link:hover span {\n  display: block;\n}\n\n/* \"?\"-specific style due to the `<a>` HTML tag */\n\n#sk-container-id-5 a.estimator_doc_link {\n  float: right;\n  font-size: 1rem;\n  line-height: 1em;\n  font-family: monospace;\n  background-color: var(--sklearn-color-background);\n  border-radius: 1rem;\n  height: 1rem;\n  width: 1rem;\n  text-decoration: none;\n  /* unfitted */\n  color: var(--sklearn-color-unfitted-level-1);\n  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n}\n\n#sk-container-id-5 a.estimator_doc_link.fitted {\n  /* fitted */\n  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n  color: var(--sklearn-color-fitted-level-1);\n}\n\n/* On hover */\n#sk-container-id-5 a.estimator_doc_link:hover {\n  /* unfitted */\n  background-color: var(--sklearn-color-unfitted-level-3);\n  color: var(--sklearn-color-background);\n  text-decoration: none;\n}\n\n#sk-container-id-5 a.estimator_doc_link.fitted:hover {\n  /* fitted */\n  background-color: var(--sklearn-color-fitted-level-3);\n}\n</style><div id=\"sk-container-id-5\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>SVC(C=0.1, class_weight=&#x27;balanced&#x27;, kernel=&#x27;linear&#x27;, random_state=42)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-5\" type=\"checkbox\" checked><label for=\"sk-estimator-id-5\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>SVC</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.6/modules/generated/sklearn.svm.SVC.html\">?<span>Documentation for SVC</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\"><pre>SVC(C=0.1, class_weight=&#x27;balanced&#x27;, kernel=&#x27;linear&#x27;, random_state=42)</pre></div> </div></div></div></div>"
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 加载鸢尾花数据集\n",
    "iris = datasets.load_iris()\n",
    "X, y = iris.data, iris.target\n",
    "# 数据标准化\n",
    "scaler = StandardScaler()\n",
    "X_scaled = scaler.fit_transform(X)\n",
    "# 划分训练集和测试集\n",
    "X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)\n",
    "# 使用SVM模型训练\n",
    "# 定义参数网格\n",
    "param_grid = {'C': [0.001, 0.01, 0.1, 1, 10],  # 减小C值以增加正则化\n",
    "              'gamma': ['scale', 'auto', 0.001, 0.01, 0.1, 1], \n",
    "              'kernel': ['linear', 'rbf']}  # 尝试线性核和RBF核\n",
    "# 使用网格搜索寻找最优参数\n",
    "grid_search = GridSearchCV(SVC(class_weight='balanced', random_state=42), param_grid, cv=5)\n",
    "grid_search.fit(X_train, y_train)\n",
    "# 输出最优参数\n",
    "print(\"Best parameters:\", grid_search.best_params_)\n",
    "# 使用最优参数训练模型\n",
    "best_model = grid_search.best_estimator_\n",
    "best_model.fit(X_train, y_train)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-04-24T07:06:48.942473Z",
     "start_time": "2025-04-24T07:06:48.283983Z"
    }
   },
   "id": "fcaa36ba56cc61af",
   "execution_count": 16
  },
  {
   "cell_type": "markdown",
   "source": [
    "## SVM模型预测与评估"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "34dbbeffac7af900"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 1.0\n",
      "Precision: 1.0\n",
      "Recall: 1.0\n",
      "F1-score: 1.0\n",
      "Confusion Matrix:\n",
      " [[10  0  0]\n",
      " [ 0  9  0]\n",
      " [ 0  0 11]]\n",
      "Classification Report:\n",
      "               precision    recall  f1-score   support\n",
      "\n",
      "           0       1.00      1.00      1.00        10\n",
      "           1       1.00      1.00      1.00         9\n",
      "           2       1.00      1.00      1.00        11\n",
      "\n",
      "    accuracy                           1.00        30\n",
      "   macro avg       1.00      1.00      1.00        30\n",
      "weighted avg       1.00      1.00      1.00        30\n",
      "\n",
      "Training set accuracy: 0.9666666666666667\n",
      "Cross-validation scores: [1.         0.93333333 1.         1.         1.         0.93333333\n",
      " 0.86666667 0.93333333 1.         1.        ]\n",
      "Mean cross-validation score: 0.9666666666666668\n"
     ]
    }
   ],
   "source": [
    "# 模型预测\n",
    "y_pred = best_model.predict(X_test)\n",
    "\n",
    "# 模型评估\n",
    "accuracy = accuracy_score(y_test, y_pred)\n",
    "precision, recall, f1, _ = precision_recall_fscore_support(y_test, y_pred, average='weighted')\n",
    "conf_matrix = confusion_matrix(y_test, y_pred)\n",
    "class_report = classification_report(y_test, y_pred)\n",
    "print(\"Accuracy:\", accuracy)\n",
    "print(\"Precision:\", precision)\n",
    "print(\"Recall:\", recall)\n",
    "print(\"F1-score:\", f1)\n",
    "print(\"Confusion Matrix:\\n\", conf_matrix)\n",
    "print(\"Classification Report:\\n\", class_report)\n",
    "# 输出训练集上的准确率\n",
    "train_accuracy = best_model.score(X_train, y_train)\n",
    "print(\"Training set accuracy:\", train_accuracy)\n",
    "\n",
    "# 使用交叉验证评估模型\n",
    "cv_scores = cross_val_score(best_model, X_scaled, y, cv=10)\n",
    "print(\"Cross-validation scores:\", cv_scores)\n",
    "print(\"Mean cross-validation score:\", np.mean(cv_scores))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-04-24T07:06:51.595500Z",
     "start_time": "2025-04-24T07:06:51.549894Z"
    }
   },
   "id": "7dd33fd1a014376d",
   "execution_count": 17
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 热度图展示混淆矩阵"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "500f266029417913"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "<Figure size 800x600 with 2 Axes>",
      "image/png": "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Uq3MkSOHXnnlFe3bt09Nmza1TGc+8sgjqlq1aqZjPnDggCpWrGhJWmrWrClfX1/lypUrw+NnzZolT09Pffrpp8qdO7ek24l68+bN9d577+mrr76yHFu/fn0NHjxYklSrVi3t2bNHO3bs0MCBA/8zrmeffVbvvPOOYmNjVaBAAUm3p20zSsxPnz6tp556Su+9954lga5du7Z27NihgwcPqkWLFpbPxN/f3+rzSU1N1eDBg/XUU09lGIe3t7cmT56sl19+WR9//LGOHTsmHx8fy/cUgGujogfYSb9+/bR792598MEHatu2rXLlyqX169frxRdf1JIlS6yObdu2rSIiIvTTTz9Juj39uH79erVo0ULe3t4Z9t+sWTP98MMPlunbjRs3qmLFiipduvR/xpaWlqbU1FTLIy0tLcPj7iQZd6YL/8udCliLFi2s2p977jm5u7tbXVXq5+dnNSXt7+8vSZm6uOB/CQkJ0Y8//qgOHTrok08+0blz5/TKK69YEuKMYm7YsKElyZMkDw8PPffcc/r555+tpmb/nXD6+/vr5s2bmYqrUaNGcnd3t0zfXrp0SYcOHcow0WvZsqXmz5+vlJQUnTlzRlu3btXMmTOVlpZmmYL+X8qXL/8/X69SpYq6du2qjz76SLt379akSZPuqvwBcE0keoAd5c2bV82bN9f48eO1detWrVmzRgEBAXr//fd19epVy3F169ZVkSJFtH79eknSjz/+qOjo6Aynbe9o0qSJzGaztm7dKknavHlzpqdtO3furIoVK1oenTt3zvC4okWLymQy/c+raq9fv25JhuLi4iRJhQoVsjrGw8ND+fPnt1pT6Ovra3XMnanhzCaV99KtWzeNGDFCSUlJmjx5spo1a6YWLVpo7969GR4fFxenggUL3tVesGBBmc1mq21s/h2zm5tbpvexy5Url+rVq2eZvt2yZYsCAgIyTMqSkpI0bNgw1ahRQy1atNCkSZP0119/ycPDI1PjZXQ+/9ayZUulp6crf/78VhVmAK6NRA94QNHR0apTp47VlN8dFSpUUHh4uJKTkxUREWFpd3d3V8uWLbV582alpqZq7dq1qlix4v+8GjN//vx68skntWXLFp0/f16nTp1Ss2bNMhXj6NGjtXLlSstj9OjRGR7n5+enihUravfu3fdMMObMmaOQkBBdvHhRefPmlaS79gVMSUnR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iR4AAICLYo0eAAAwHNboAQAAIFujogcAAAzHKPvokegBAADDYeoWAAAA2RoVPQAAYDgGKehR0QMAAHBVVPQAAIDxGKSkR0UPAADARVHRAwAAhmOU7VWo6AEAALgoKnoAAMBw2EcPAAAA2RoVPQAAYDgGKeiR6AEAAAMySKbH1C0AAICLItEDAACGY3Lgf7aKjY3VG2+8oaCgIIWEhGj8+PFKTU21y3mS6AEAADhReHi4cuTIod27d2vlypXau3evFi9ebJe+SfQAAIDhmEyOe9jizz//1IEDB/T222/L19dXJUuW1BtvvKGlS5fa5Ty5GAMAAMCOkpOTlZycbNXm5eUlLy+vu449c+aM8uXLpyJFiljaypYtq6ioKF2/fl158uR5oFhcItHzcYmzAADHSjwyy9khAFmGI3OHmTPnadYs6//fevfurT59+tx1bEJCgnx9fa3a7jy/efMmiR4AAEBW0qNHD3Xp0sWqLaNqniTlyJFDiYmJVm13nufMmfOBYyHRAwAAsKN7TdNmpFy5crp27ZouX76sggULSpLOnTsnf39/5c6d+4Fj4WIMAAAAJyldurRq1KihCRMmKD4+XhEREZo9e7batm1rl/5NZrPZbJeeAAAAYLPLly9rzJgx2r9/v9zc3NSyZUu99dZbcnd3f+C+SfQAAABcFFO3AAAALopEDwAAwEWR6AEAALgoEj0DO3/+vLNDAAAADkSiZ1C//PKLmjdv7uwwgAw999xzWrdu3QP18ddffykwMFB//fWXnaJCdhYVFaVq1aopKirqvt4/YsQIjRgxIlPHduvWTXPnzr2vcQB746pbg9q/f79effVV/frrr84OBXCIv/76S08//bS2bdumEiVKODscAHAKKnouYObMmapfv75q1qypNm3aaNu2bZKkkydPKiwsTMHBwWrSpIkWL14ss9msiIgIde/eXZJUrVo1HTlyROnp6fr444/VqFEj1ahRQ23bttXu3bstY3zzzTd67rnnVKNGDT377LOaPXu25bWffvpJr776qurUqaNKlSqpdevWOnr06EP9DPBwDBo0SAMHDrRqCw8P1+jRo3XhwgX17NlTISEhatiwoaZOnWq5qffq1avVunVrvfbaawoKCtL69et18OBBtW7dWkFBQWrcuLHGjx+v1NRUSVJoaKhWr14t6fa9HseMGaNatWopKChI3bt3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eXp6KioqSjlz5lRSUpLi4uIsx/Tt21fFixdXrly5NGjQIO3bt0/R0dFat26dypYtq44dO8rT01MBAQHq2rWr5fMBgKyANXqAQYwcOdJqjV5GChcubPk5MjJSV65cUXBwsKXNbDYrJSVFsbGxio6OVsWKFa3eX7JkyQz7jYmJUbFixazaqlevftdxV65c0c2bN9WvXz+5uf3fv0NTUlIUGRmp5ORk5c+f3ypBfOSRR/7nOf0vERERmjJlis6fP6/SpUurVKlSkmR1gUqJEiUsP985h+joaEVGRurkyZMKCgqyvJ6eni53d/f7jgcA7I1ED4CFyWSy/Ozv769HHnlEW7ZssbTFx8crNjZWfn5+8vf3V0REhNX7//77b5UrV+6ufosWLaqLFy9atU2dOlXPP/+8VVv+/Pnl7e2tRYsWqWrVqpb233//XUWKFNGpU6d05coVJSQkKGfOnJYx78edaeABAwaoQ4cOMplMOnHihNatW2d13KVLl/TYY49JkuV8S5QoIX9/f4WEhGjhwoWWY69evWo17QsAzsbULYAMNWzYUAkJCVqwYIGSk5N1/fp1DR48WP3795fJZFKbNm20detWff/990pNTdWaNWt07NixDPtq3bq1li9fruPHjys9PV2rVq3S0qVLLYldYmKiUlNT5ebmprZt2+qDDz7Q33//rfT0dK1Zs0bNmzfXn3/+qWrVqunRRx/VuHHjlJiYqD///FOLFi36z3P5+++/rR6XLl1SSkqKkpKS5OPjI5PJpKioKL333nuSbieBd8ycOVPR0dGKi4vTpEmT1KRJE/n5+alFixY6evSo1q1bp9TUVF26dEk9e/bUpEmT7PMHAAB2QEUPQIZy5cqlxYsXa9KkSVqwYIHS09MVEhKiOXPmSJJq1KihKVOmaNKkSerfv7+efPJJqws7/qlFixa6fv263n77bcXExCggIEDz58+Xn5+fgoODVaBAAQUHB+vLL7/U4MGDNXPmTHXo0EHXrl1TyZIlNWPGDMv6v48//lgjRozQU089pYIFC+rpp5/Wt99++z/PpX79+lbPCxYsqD179mjChAmaPn26xo0bpwIFCqh9+/Y6e/asfvvtNz366KOSpLp166p9+/ZKSkpSw4YN9c4770iSihcvrgULFuj999/XuHHj5O7urgYNGmjYsGEP9LkDgD2ZzOwFAAAA4JKYugUAAHBRJHoAAAAuikQPAADARZHoAQAAuCgSPQAAABdFogcAAOCiSPQAAABcFIkeAACAiyLRAwAAcFEkegAAAC6KRA8AAMBF/T+bxb3mtWw8DAAAAABJRU5ErkJggg=="
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 使用热度图展示混淆矩阵，体现每个类别的识别效果\n",
    "plt.figure(figsize=(8, 6))\n",
    "sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', xticklabels=iris.target_names, yticklabels=iris.target_names)\n",
    "plt.title(\"SVM - Confusion Matrix\")\n",
    "plt.xlabel(\"Predicted Label\")\n",
    "plt.ylabel(\"True Label\")\n",
    "plt.show()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-04-24T07:07:07.917076Z",
     "start_time": "2025-04-24T07:07:07.757194Z"
    }
   },
   "id": "a18431ef94acc94f",
   "execution_count": 18
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false
   },
   "id": "57c03b142a4f9e75"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
